package ListFIFO(mkListFIFOF, mkListFIFO) where
import FIFO
import FIFOF
import List
import ListReg

--@ \subsubsection{ListFIFO}
--@ \index{ListFIFO@\te{ListFIFO} (package)|textbf}
--@
--@ The \te{ListFIFO} package provides constructors for making FIFOs for
--@ values of type \te{List}.
--@ \begin{libverbatim}
--@ module mkListFIFOF#(Integer n)(FIFOF#(List#(a)))
--@   provisos (Bits#(a, sa));
--@ \end{libverbatim}
mkListFIFOF :: (IsModule m c, Bits a sa) => Integer -> m (FIFOF (List a))
mkListFIFOF n =
    module
        r1 <- mkListReg (replicate n _)
        r2 <- mkListReg (replicate n _)
        rNotFull <- mkReg True
        rNotEmpty <- mkReg False
        interface FIFOF
            enq x    = if rNotEmpty then action { r1 := x; rNotFull := False; } else action { r2 := x; rNotEmpty := True }
            deq      = action { r2 := r1; rNotFull := True; rNotEmpty := not rNotFull }
            first    = r2
            notFull  = rNotFull
            notEmpty = rNotEmpty
            clear    = action { rNotFull := True; rNotEmpty := False }

--@ \begin{libverbatim}
--@ module mkListFIFO#(Integer n)(FIFO#(List#(a)))
--@   provisos (Bits#(a, sa));
--@ \end{libverbatim}
mkListFIFO :: (IsModule m c, Bits a sa) => Integer -> m (FIFO (List a))
mkListFIFO n = do
    _f <- mkListFIFOF n
    return (fifofToFifo _f)

